package com.autotest.sync.android;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.text.DecimalFormat;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;

import com.autotest.sync.Config;
import com.autotest.sync.utils.SystemCmdUtil;
import com.autotest.sync.utils.ThreadManager;
import com.autotest.sync.utils.TimeUtil;

/**
 * 解析相关命令，核心
 * @author zy
 *
 */
public class MasterDevice {
	public String serial;
	private String mInputEvent;
	private boolean mFlagPause = false;
	private Process mProc = null;
	private BufferedReader mBr = null;
	private float w = 0;
	private float h = 0;
	private String x = null;
	private String y = null; 
	private String current_event = null;
	DecimalFormat df = new DecimalFormat("#.00000000000000");;
	
	static class EventKey{ //需要处理的相关事件key
		public static final String DOWN = "EV_KEY BTN_TOUCH DOWN";
		public static final String UP = "EV_KEY BTN_TOUCH UP";
		public static final String SYN_REPORT = "EV_SYN SYN_REPORT";
		public static final String POSITION_X = "EV_ABS ABS_MT_POSITION_X";
		public static final String POSITION_Y = "EV_ABS ABS_MT_POSITION_Y";
		public static final String KEY_BACK = "KEY_BACK";
		public static final String KEY_POWER = "KEY_POWER";
		public static final String KEY_VOLUMEDOWN = "KEY_VOLUMEDOWN";
		public static final String KEY_VOLUMEUP = "KEY_VOLUMEUP";
		
	}
	
	public MasterDevice(String serial){
		this.serial = serial;
	}
	
	public MasterDevice(String serial, String inputEvent){
		this.serial = serial;
		if(!StringUtils.isBlank(inputEvent)){
			mInputEvent = inputEvent;
		}
	}
	
	/**
	 * 查看操作系统类型
	 * @return
	 */
	public boolean isWinOsType(){
		String osName = System.getProperty("os.name");
		if(osName.matches("(?i)windows.*")){
			return true;
		}
		return false;
	}
	
	private void prepare(){
		String result = SystemCmdUtil.rexec(String.format("adb -s %s shell  getevent -p", serial));
		Pattern event = Pattern.compile(".*(/dev/input/event\\d+).*");
		Pattern r = Pattern.compile(".*max (\\d+).*");
		for(String line : result.split("\n")){
			if(StringUtils.isBlank(line.trim())){
				continue;
			}
			Matcher m_event = event.matcher(line);
			if(m_event.find()){
				mInputEvent = m_event.group(1);
			}
			if(line.indexOf("0035")==0){
				Matcher m = r.matcher(line);
			    if (m.find( )) {
			    	w = Float.parseFloat(m.group(1));
			    }
			}else if(line.indexOf("0036")==0){
				Matcher m = r.matcher(line);
			    if (m.find( )) {
			    	h = Float.parseFloat(m.group(1));
			    }
			}
			if(w > 0 && h >0){
				break;
			}
		}
	}
	
	private void prepareHas(){//预先有inputevent
		boolean flag = false;
		String result = SystemCmdUtil.rexec(String.format("adb -s %s shell  getevent -p", serial));
		Pattern event = Pattern.compile(String.format(".*(%s).*",mInputEvent));
		Pattern r = Pattern.compile(".*max (\\d+).*");
		for(String line : result.split("\n")){
			if(StringUtils.isBlank(line.trim())){
				continue;
			}
			Matcher m_event = event.matcher(line);
			if(m_event.find()){
				flag = true;
			}
			if(flag){
				if(line.indexOf("0035")==0){
					Matcher m = r.matcher(line);
				    if (m.find( )) {
				    	w = Float.parseFloat(m.group(1));
				    }
				}else if(line.indexOf("0036")==0){
					Matcher m = r.matcher(line);
				    if (m.find( )) {
				    	h = Float.parseFloat(m.group(1));
				    }
				}
				if(w > 0 && h >0){
					break;
				}
			}
			
		}
	}
	
	
	
	
	@Override
	public String toString() {
		return String.format("serial: %s, input: %s, w: %s h: %s", serial,mInputEvent,w,h);
	}

	public void start(){
		if(mInputEvent == null){
			prepare();
		}else{
			prepareHas();
		}
		startParse();
		
	}
	
	public void startParse(){
//		String cmd = String.format("adb -s %s shell getevent -l %s", serial,mInputEvent);
		String cmd = String.format("adb -s %s shell getevent -l", serial);
		try {
			ProcessBuilder pb = new ProcessBuilder(cmd.split(" "));
			pb.redirectErrorStream(true);
			mProc = pb.start();
			mBr = new BufferedReader(new InputStreamReader(mProc.getInputStream(), "utf-8"));
			String line = null;
			while ((line = mBr.readLine()) != null) {
				if(StringUtils.isBlank(line.trim()) || mFlagPause){
					continue;
				}
				parseCmd(line.replaceAll("\\s+", " ").trim());
			}
		} catch (Exception e) {
//			e.printStackTrace();
		} finally {
			IOUtils.closeQuietly(mBr);
			if (mProc != null) {
				mProc.destroy();
			}
		}
	}
	
	public void restart(){
		startParse();
	}
	
	public void setPause(){
		mFlagPause = !mFlagPause;
	}
	
	public void stop(){
		IOUtils.closeQuietly(mBr);
		if(mProc != null){
			mProc.destroyForcibly();
			mProc = null;
		}
	}
	/**
	 * 解析关心的相关命令
	 * @param line
	 */
	private void parseCmd(String line){
		if(Config.Flag_Log){
			System.out.println(line);
		}
		if(line != null && mInputEvent != null){
			if(line.startsWith(mInputEvent)){
				line = line.replace(mInputEvent+":", "").trim();
				if(line.startsWith(EventKey.UP)){
					MyEventBus.getInstance().post("2:up");
					return;
				}
				if(line.startsWith(EventKey.DOWN)){
					current_event = EventKey.DOWN;
				}else if(line.startsWith(EventKey.SYN_REPORT)){
					current_event = EventKey.SYN_REPORT;
				}else if(line.startsWith(EventKey.POSITION_X)){
					String pos_x = line.replace(EventKey.POSITION_X, "").trim();
					Long l_pos_x = Long.parseLong(pos_x, 16);
					x = df.format(l_pos_x/w).toString();
				}else if(line.startsWith(EventKey.POSITION_Y)){
					String pos_y = line.replace(EventKey.POSITION_Y, "").trim();
					Long l_pos_y = Long.parseLong(pos_y, 16);
					y = df.format(l_pos_y/h).toString();
				}
				if(x != null && y!= null){
					sendCmd();
					x = null;
					y = null;
				}
			}else{
				if(line.contains("KEY_BACK UP")){
					current_event = EventKey.KEY_BACK;
					sendCmd();
				}else if(line.contains("KEY_POWER UP")){
					current_event = EventKey.KEY_POWER;
					sendCmd();
				}else if(line.contains("KEY_VOLUMEDOWN UP")){
					current_event = EventKey.KEY_VOLUMEDOWN;
					sendCmd();
				}else if(line.contains("KEY_VOLUMEUP UP")){
					current_event = EventKey.KEY_VOLUMEUP;
					sendCmd();
				}
			}
		}
		
	}
	
	private void sendCmd(){
		if(current_event == null){
			return;
		}
		switch(current_event){
		case EventKey.DOWN:
			double s = Double.parseDouble(y);
			if(s<1){
				MyEventBus.getInstance().post(String.format("1:%s,%s", x,y));
			}else{
				MyEventBus.getInstance().post("4:4");
			}
			break;
		case EventKey.SYN_REPORT:
			MyEventBus.getInstance().post(String.format("3:%s,%s", x,y));
			break;
		case EventKey.KEY_BACK:
			MyEventBus.getInstance().post("4:4");
			break;
		case EventKey.KEY_POWER:
			MyEventBus.getInstance().post("4:26");
			break;
		case EventKey.KEY_VOLUMEDOWN:
			MyEventBus.getInstance().post("4:25");
			break;
		case EventKey.KEY_VOLUMEUP:
			MyEventBus.getInstance().post("4:24");
			break;
		default:
			break;
		}
	}
	
	public static void main(String[] args) {
		SlaveDevice tt = new SlaveDevice("bdb6c403");
		MyEventBus.getInstance().register(tt);
		ThreadManager.getInstance().start(()->tt.startMiniTouch());
		MasterDevice master = new MasterDevice("TO8DKFIZ99999999");
		master.start();
		while(true){
			TimeUtil.sleep(2000);
		}
	}
}
